package xxl.robotlegs.extensions.mediatormap.impl 
{
	import flash.utils.Dictionary;
	import xxl.robotlegs.extensions.matching.impl.TypeMatcher;
	import xxl.robotlegs.extensions.mediatormap.api.IMediatorUnmapper;
	import flash.display.DisplayObject;
	import xxl.robotlegs.extensions.matching.api.ITypeMatcher;
	import xxl.robotlegs.extensions.mediatormap.api.IMediatorMap;
	import xxl.robotlegs.extensions.mediatormap.api.IMediatorMapper;
	import xxl.robotlegs.extensions.viewmanager.api.IViewHandler;
	import xxl.robotlegs.framework.api.IContext;
	import xxl.robotlegs.framework.api.ILogger;
	/**
	 * ...
	 * @author XXL
	 */
	public class MediatorMap implements IMediatorMap, IViewHandler
	{
		private const _mappers:Dictionary = new Dictionary();
		private var _logger:ILogger;
		private var _factory:MediatorFactory;
		private var _viewHandler:MediatorViewHandler;
		private const NULL_UNMAPPER:IMediatorUnmapper = new NullMediatorUnmapper();
		
		public function MediatorMap(context:IContext) 
		{
			_logger = context.getLogger(this);
			_factory = new MediatorFactory(context.injector);
			_viewHandler = new MediatorViewHandler(_factory);
		}
		
		private function createMapper(matcher:ITypeMatcher):IMediatorMapper
		{
			return new MediatorMapper(matcher.createTypeFilter(), _viewHandler, _logger);
		}
		
		/* INTERFACE xxl.robotlegs.extensions.viewmanager.api.IViewHandler */
		
		public function handleView(view:DisplayObject, type:Class):void 
		{
			_viewHandler.handleView(view, type);
		}
		
		/* INTERFACE xxl.robotlegs.extensions.mediatormap.api.IMediatorMap */
		
		public function mapMatcher(matcher:ITypeMatcher):IMediatorMapper 
		{
			return _mappers[matcher.createTypeFilter().descriptor] ||= createMapper(matcher);
		}
		
		public function map(type:Class):IMediatorMapper 
		{
			return mapMatcher(new TypeMatcher().allOf(type));
		}
		
		public function unmapMatcher(matcher:ITypeMatcher):IMediatorUnmapper 
		{
			return _mappers[matcher.createTypeFilter().descriptor] || NULL_UNMAPPER;
		}
		
		public function unmap(type:Class):IMediatorUnmapper 
		{
			return unmapMatcher(new TypeMatcher().allOf(type));
		}
		
		public function mediate(item:Object):void 
		{
			_viewHandler.handleItem(item, item["constructor"] as Class);
		}
		
		public function unmediate(item:Object):void 
		{
			_factory.removeMediators(item);
		}
		
		public function unmediateAll():void 
		{
			_factory.removeAllMediators();
		}
		
	}

}